#include "network_base.h"
#include <core/QbLogger.h>
#include <assert.h>
#ifdef _MSC_VER
#include <WinSock.h>
#else
#include "../sock/socket_inc.h"
#endif

namespace qb
{
	CSocketBase::CSocketBase(SocketType sock_type)
		: m_callbackCritSect(*CriticalSectionWrapper::CreateCriticalSection())
		, m_sock_type(sock_type)
		, m_socket_id(-1)
	{
	}

	CSocketBase::~CSocketBase(void)
	{
		assert(0 == m_observers.size());
		RemoveObserver<INetworkServiceObserver>(m_observers);

		delete &m_callbackCritSect;
	}

	int32_t CSocketBase::InitlizeSocket(int32_t socket_id)
	{
		m_socket_id = socket_id;

		return 0;
	}

	int32_t CSocketBase::RegisterSocketObserver(INetworkServiceObserver* observer)
	{
		log_info("(%d)",m_socket_id);
		CSocketImpl::RegisterSocketObserver(this);
		
		CriticalSectionScoped cs(&m_callbackCritSect);
		RegisterObserver<INetworkServiceObserver>(observer, m_observers);

		return 0;
	}

	int32_t CSocketBase::DeRegisterSocketObserver(INetworkServiceObserver* observer)
	{
		log_info("(%d)",m_socket_id);
		CSocketImpl::DeRegisterSocketObserver();

		CriticalSectionScoped cs(&m_callbackCritSect);
		DeRegisterObserver<INetworkServiceObserver>(observer, m_observers);

		return 0;
	}

	int32_t CSocketBase::Connect(const char* ipAddressUTF8,uint16_t port)
	{
		return CSocketImpl::Connect(ipAddressUTF8,port,m_sock_type == kSocketTcp ? IPPROTO_TCP : IPPROTO_UDP);
	}

	void CSocketBase::OnConnected()
	{
		CriticalSectionScoped cs(&m_callbackCritSect);
		assert(m_socket_id > -1);

		BList<INetworkServiceObserver*>::iterator iter = m_observers.begin();
		for_each_list(m_observers, iter, (iter++)->first->OnConnect(m_socket_id, kConnectConnected));
	}

	void CSocketBase::OnSendFailed()
	{
		CriticalSectionScoped cs(&m_callbackCritSect);
		assert(m_socket_id > -1);

		BList<INetworkServiceObserver*>::iterator iter = m_observers.begin();
		for_each_list(m_observers, iter, (iter++)->first->OnFailed(m_socket_id, kConnectSendError));

		log_error("network error,(err=%d) ", CSocketWrapper::GetSockError());
	}

	void CSocketBase::OnRecvFailed()
	{
		CriticalSectionScoped cs(&m_callbackCritSect);
		assert(m_socket_id > -1);

		BList<INetworkServiceObserver*>::iterator iter = m_observers.begin();
		for_each_list(m_observers, iter, (iter++)->first->OnFailed(m_socket_id, KConnectRecvError));

		log_error("network error,(err=%d) ", CSocketWrapper::GetSockError());
	}

    void CSocketBase::OnRecvMessage(MESSAGE_SHARED_PTR msp)
    {
        CriticalSectionScoped cs(&m_callbackCritSect);
        assert(m_socket_id > -1);

		BList<INetworkServiceObserver*>::iterator iter = m_observers.begin();
		for_each_list(m_observers, iter, (iter++)->first->OnReceive(m_socket_id, msp));
    }

    void CSocketBase::OnRecvMessage2(const char* buf,uint32_t buf_size)
	{
		CriticalSectionScoped cs(&m_callbackCritSect);
		assert(m_socket_id > -1);

		BList<INetworkServiceObserver*>::iterator iter = m_observers.begin();
		for_each_list(m_observers, iter, (iter++)->first->OnReceive2(m_socket_id, buf, buf_size));
	}
}
